<template>
  <div v-if="socket">ws连接成功</div>

  <button @click="socket.post({
    type: 'media',
    request: 'getBaseInfo',
    param: {
      // mediaPath: 'C:/Users/haha/Videos/obs/123.ts',
      mediaPath: mediaAddr,
      internalPath: binAddr
    }
  })">获取视频基本信息</button>

  <button @click="socket.post({
    type: 'media',
    request: 'getFramesLenth',
    param: {
      mediaPath: mediaAddr,
      internalPath: binAddr
    }
  })">获取视频实际总帧数</button>

  <button v-bind:disabled="!mediaFrameLength" @click="playFrame(getFramesEachTime)">开始播放</button>
  <div id="play-wrapper">
    <img :src="frame" alt="">
    <img :src="frameSaved" alt="">
  </div>
</template>


<script setup>
import { ref, onMounted } from 'vue'

import { msg } from './assets/scripts/function.lib'
import { ws } from './assets/scripts/websocket'

const mediaAddr = ref('G:/海绵宝宝/海绵宝宝 国语 12季/海绵宝宝 第1季/海绵宝宝 第1季 第1集_896x672_H265_22.46_115.51MB.mp4')
const binAddr = ref('E:/MyProject/js脚本/git/ffmpegTEST/internal')

// 视频总帧数
const mediaFrameLength = ref(null)
// 平均帧率
const avgFrameRate = ref(null)

// 单次获取帧数
const getFramesEachTime = ref(240)
// 总缓
const frameCache = {}
const frameArray = []
const frame = ref(null)
// 一缓
const frameSaved = ref(null)

const socket = ref(null)

const conf = {
  port: 59420
}

let timer
function playFrame(tempLen) {
  // timer = setInterval(() => {
  //   socket.value.post({
  //     type: 'media',
  //     request: 'getFrames',
  //     param: {
  //       start: fi++,
  //       mediaPath: 'C:/Users/haha/Videos/obs/123.ts',
  //       internalPath: 'E:/MyProject/js脚本/git/ffmpegTEST/internal'
  //     }
  //   })

  //   fi += 1
  //   if (fi > 800) {
  //     clearInterval(timer)
  //   }
  // }, 1000 / 30)

  let mfl = parseInt(mediaFrameLength.value)

  const startPlay = () => {
    let playTimer
    playTimer = setInterval(() => {
      frame.value = frameArray.shift()
      frameSaved.value = frame.value.slice()

      if (!mfl) clearInterval(playTimer)
    }, 1000 / avgFrameRate.value)
  }

  const get = () => {
    let curr = mediaFrameLength.value - mfl
    return new Promise(resolve => {
      let tmp = mfl - tempLen
      if (tmp > 0) {
        if (tmp < tempLen) tempLen = tempLen
        mfl -= tempLen

        for (let i = curr; i < tempLen + curr; i++) {
          socket.value.post({
            type: 'media',
            request: 'getFrames',
            param: {
              start: i,
              mediaPath: mediaAddr.value,
              internalPath: binAddr.value
            }
          })
        }

        timer = setInterval(() => {
          if (Object.keys(frameCache).length == tempLen) {
            // console.log(frameCache)

            Object.keys(frameCache).forEach(i => {
              frameArray.push(frameCache[i])
              delete frameCache[i]
            })

            // console.log(frameArray)
            resolve()


            clearInterval(timer)

            if (mfl > 0) {
              get()
            } else {
              console.log('播放完成');
            }
          }
        }, 1000 / 60)
      } else {
        console.log('播放完成');
      }
    })
  }

  get()
    .then(() => {
      startPlay()
    })


}

function handleWS(smsg, websocket) {
  const data = smsg.data
  switch (smsg.header.response) {
    case 'check':
      if (data == 'ok') {
        msg({
          text: `**Websocket** 连接成功，收到回复：**<font color='#98c379'>${JSON.stringify(smsg)}<font>**`,
          delay: 3000
        })

        console.log(websocket);

        socket.value = websocket
      } else {
        msg('ws连接失败')
        console.log(smsg);

      }
      break;

    case 'media-getBaseInfo':
      const metadata = smsg.data

      // 获取视频时长（秒）
      const duration = parseFloat(metadata.format.duration);
      console.log(`视频时长: ${duration.toFixed(2)} 秒`);

      // 获取视频流
      const videoStream = metadata.streams.find(s => s.codec_type === 'video');
      if (!videoStream) {
        throw new Error('未找到视频流');
      }

      avgFrameRate.value = parseInt(videoStream.avg_frame_rate)

      // 获取总帧数的三种方式（按优先级排序）
      let totalFrames;

      // 方式1：直接获取 nb_frames（最准确）
      if (videoStream.nb_frames) {
        totalFrames = parseInt(videoStream.nb_frames);
      }
      // 方式2：通过帧率计算（当视频有固定帧率时）
      else if (videoStream.avg_frame_rate) {
        const [numerator, denominator] = videoStream.avg_frame_rate.split('/').map(Number);
        const fps = numerator / denominator;
        totalFrames = Math.round(duration * fps);
      }
      // 方式3：通过持续时间计算（当有 r_frame_rate 时）
      else if (videoStream.r_frame_rate) {
        const [numerator, denominator] = videoStream.r_frame_rate.split('/').map(Number);
        const fps = numerator / denominator;
        totalFrames = Math.round(duration * fps);
      }
      else {
        throw new Error('无法确定视频帧率');
      }

      mediaFrameLength.value = totalFrames

      console.log(`总帧数: ${totalFrames}`);
      break

    case 'media-getFramesLenth':

      mediaFrameLength.value = parseInt(data)

      break

    case 'media-getFrames':
      let sp = data.indexOf('-')
      frameCache[data.substr(0, sp)] = data.slice(++sp)



      // frame.value = data
      // console.log(data)

      break
    default:
      break;
  }
}


onMounted(() => {
  ws(conf.port, { type: 'check' }, handleWS)

})
</script>

<style scoped>
#play-wrapper {
  position: relative;
  width: 90%;
  margin-left: 5%;

  img {
    position: absolute;
  }
}
</style>